<?php

require_once('Autoloader.php');
Autoloader::setCacheFilePath('./class_path_cache.txt');
Autoloader::excludeFolderNamesMatchingRegex('/^CVS|\..*$/');
Autoloader::setClassPaths(array(
     './','../','Blocks/'
	 
));
spl_autoload_register(array('Autoloader', 'loadClass'));




/**
* 
*/
class TE
{	
	/**
	* Block es un bloque de texto cortado desde la plantilla.
	* @var $block fragmento de un texto.
	*/
	public $block = "";
	
	public function __construct($param="",$block="")
	{	
		
		$this->block = $block;
		$this->initialize();
	}
	
	public function initialize(){
		;
	}
	
	public function __toString(){
		
		return (method_exists($this,"show")?$this->show():"");
	}
	
	public function dump(){
		$data=array();
		$result="";
		foreach(get_object_vars($this) as $var => $value ){
			if(is_object($this->$var)){
			
				$classname = get_class($this->$var);
				
				$result.=  " <fieldset><legend>$classname $var</legend> ".
				(!is_null($this->$var)?$this->$var->dump():"")
				."</fieldset> ";
			}else{
				
				if($var=="args" && !empty($value)){
					$data['params'] = $value;
					
				}elseif($var=="block"){
					$data['block'] = $value;
				}else{
					$data['tags'][$var] = $value;
				
				}
			}
		}
		if(isset($data['params'])){
			$result.="Params ".$data['params']." ";
		}
		if(isset($data['tags'])){
		
			if($c=count($data['tags'])){
				$result.="$c Tags ";
			}
			foreach($data['tags'] as $var => $value){
		
				$result.= "<span style='border:1px solid black; margin:2;padding:2; background-color:lightyellow'>{{$var}}</span>";
			}
		}
		
		if(isset($data['block']) &&!empty($data['block']) ){
			$result.="<fieldset><legend>Block</legend> <textarea>".$data['block']."</textarea>
			<div style='border:1px solid black; margin:2;padding:2; background-color:lightyellow'>".$data['block']."</div></fieldset>";
		}
		
		return $result;
	}

	public function isBlock($obj=""){
		if(empty($obj)){
			return true;
		}else{
			return method_exists($obj,"isBlock");
		}
	
	}
	
	public function has($var){
		return isset($this->$var);
	}
	
	public function set($var,$value=""){
		$this->$var = $value;
	}
	
	public function get($var){
		return (isset($this->$var)?$this->$var:"");
	}
	
	public function setBlock($block=""){
		return $this->set("block",$block);
	}
	
	public function getBlock(){
		return $this->get("block");
	}
	
	public function append($class,$block){
		$this->set($class,  $this->get($class).$block );
	}
	
	public function prepend($class,$block){
		$this->set($class,  $block.$this->get($class) );
	}
	
	
	public function replaceTag(array $match){
		if(isset($match[1])){
				return $this->get($match[1]);
			}else{
				return "";
			}
	}
	
	public function replaceBlock(array $match){
		if(isset($match[1])){
				$class=$match[1];
				$oid=(isset($match[2])?$match[2]:"");
				
				$param = $this->parseArguments((isset($match[3])?$match[3]:""));
				$param['oid']=$oid;
				
				$block=(isset($match[4])?$match[4]:"");
				
				$this->$oid = new $class($param,$block);
				$this->$oid->oid=$oid;
				
				foreach($param as $property => $value){
					
					$this->$oid->$property = preg_replace_callback("/\_\(\s*(.*)\s*\)/U", array($this,'replaceLiteral'), $value);
				}
				$this->$oid->parse($block);
				
				
				return "{".$oid."}";
			}else{
				return "";
			}
	}
	
	public function replaceMethod(array $match){
		if(isset($match[1])){
				$method=$match[1];
				$param=$this->parseArguments((isset($match[2])?$match[2]:""));
				$param['method']=$method;
				$block=(isset($match[3])?$match[3]:"");
				$this->parse($block);
				
				
				if( method_exists($this,$method)){
					$text = $this->$method($param,$block);
				} else {
					$text = "";
				}	
				return $text;
							
			}else{
				return "";
			}
	}
	
	public function translate($literal){
		return $literal;
	}
	
	
	public function replaceLiteral(array $match){
		if(isset($match[1])){
			$literal = $match[1] ;
		}else{
			$literal="";
		}	
		return $this->filter( $this->translate($literal) );
	}
	
	public function replace($block=""){
		$text = ($block?$block:$this->block);
		
		//Tags
		$text = preg_replace_callback('/\{\s*\$(\S+)\s*\}/U', array($this,'replaceTag'), $text);
		$text = preg_replace_callback('/\{\s*(\S+)\s*\}/U', array($this,'replaceTag'), $text);
		
		// Internationalization
		$text = preg_replace_callback("/\_\(\s*(.*)\s*\)/U", array($this,'replaceLiteral'), $text);
		
		return $text;
	}
	
	private function parseArguments($args){
		
		$argl['args']=$args;

		preg_match_all("/(\S+)\s*=\s*(['\"])\s*(.*)\s*\g{2}/U",$args,$match, PREG_PATTERN_ORDER);
 
 
		if(isset($match[1])){
			foreach($match[1] as $key=> $var){
				$argl[$var]=(isset($match[3][$key])?$match[3][$key]:"");
			}
		}
		return $argl;
	}
	
	
	public function parse($text){
		$class = "\S+";
		$id    = "[^\s\|]+";
		$args1 = "[^\}]*";
		$args2 = "[^\|]*";
		$block = ".*?";
		// Object
		$text = preg_replace_callback("/\{\s*($class)\s*($id)\s*\|($args1)\}($block)\{\s*\|\s*\g{2}\s*\}/s", array($this,'replaceBlock'), $text);
		$text = preg_replace_callback("/\{\s*($class)\s*($id)\s*\|($args2)\|\s*\}/Us", array($this,'replaceBlock'), $text);
		
		// Method
	    $text = preg_replace_callback("/\{\s*($id)\s*\|($args2)\|\s*\}/Us", array($this,'replaceMethod'), $text);
		$text = preg_replace_callback("/\{\s*($id)\s*\|($args1)\}($block)\{\s*\|\s*\g{1}\s*\}/s", array($this,'replaceMethod'), $text);

		
		$this->block = $text;
		
		return $text;
	}
	
	public function parseFromFile($filePath){
	
		if(file_exists($filePath)){
			return $this->parse(file_get_contents($filePath));
		}else{
			return "Error: No encontrado $filePath";
		}
	}
	function filter($text){
		return htmlentities($text);
	}
}





?>